<?php

namespace app\admin\model\workorder;

use think\Db;
use think\Model;
use think\Exception;
use app\common\model\Config;
use think\exception\PDOException;
use addons\workorder\library\SQLLib;


class Fields extends Model
{

    // 表名
    protected $name = 'workorder_fields';

    // 数据表名
    protected static $dataTable = 'workorder_orders';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = false;
    protected $deleteTime = false;

    // 追加属性
    protected $append = [
        'position_text',
        'type_list_text',
        'status_text',
        'values_list',
        'isrequire',
        'isbasicinfo_text',
        'autofill_text',
    ];

    protected static $listField = ['select', 'selects', 'checkbox', 'radio'];


    protected static function init()
    {
        $beforeUpdateCallback = function ($row) {

            if (!preg_match("/^([a-zA-Z0-9_]+)$/i", $row['name'])) {
                throw new Exception(__('Fields only support alphanumeric underscores!'));
            }
            if (is_numeric(substr($row['name'], 0, 1))) {
                throw new Exception(__('Field cannot start with a number!'));
            }

            if (isset($row['oldname']) && $row['oldname'] != $row['name'] && $row['position'] != 0) {
                $tableFields = Db::name(self::$dataTable)->getTableFields();
                if (in_array(strtolower($row['name']), $tableFields)) {
                    throw new Exception(__('This field already exists!'));
                }
            }
        };

        self::beforeInsert($beforeUpdateCallback);
        self::beforeUpdate($beforeUpdateCallback);

        self::afterInsert(function ($row) {
            if ($row['position'] == 0) {
                $pk = $row->getPk();
                $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);

                // 向数据表添加字段
                $sql = SQLLib::instance()
                    ->setTable(self::$dataTable)
                    ->setName($row['name'])
                    ->setFieldLength($row['field_length'])
                    ->setValues($row['values'])
                    ->setDecimals($row['decimals'])
                    ->setDefaultvalue($row['default'])
                    ->setComment($row['title'])
                    ->setType($row['type_list'])
                    ->getAddSql();
                try {
                    db()->query($sql);
                } catch (PDOException $e) {
                    $row->getQuery()->where('id', $row->id)->delete();
                    throw new Exception($e->getMessage());
                }
            }
        });

        self::afterUpdate(function ($row) {
            if ($row['position'] == 0) {
                $sqlLib = SQLLib::instance();
                if (isset($row['oldname']) && $row['oldname'] != $row['name']) {
                    $sqlLib->setOldname($row['oldname']);
                }
                $sql = $sqlLib->setTable(self::$dataTable)
                    ->setName($row['name'])
                    ->setFieldLength($row['field_length'])
                    ->setValues($row['values'])
                    ->setDecimals($row['decimals'])
                    ->setDefaultvalue($row['default'])
                    ->setComment($row['title'])
                    ->setType($row['type_list'])
                    ->getModifySql();
                try {
                    db()->query($sql);
                } catch (PDOException $e) {
                    throw new Exception($e->getMessage());
                }
            }
        });

        self::afterDelete(function ($row) {
            if ($row['position'] == 0) {
                $sql = SQLLib::instance()->setTable(self::$dataTable)->setName($row['name'])->getDropSql();
                db()->query($sql);
            }
        });
    }

    public function getIsrequireAttr($value, $data)
    {
        return $data['rule'] && in_array('required', explode('; ', $data['rule']));
    }

    public function getValuesListAttr($value, $data)
    {
        return in_array($data['type_list'], self::$listField) ? Config::decode($data['values']) : $data['values'];
    }

    public function getPositionList()
    {
        return [
            '0' => __('Position 0'),
            '1' => __('Position 1'),
            '2' => __('Position 2')
        ];
    }

    public function getTypeListList()
    {
        return [
            'string'   => __('Type_list string'),
            'textarea' => __('Type_list textarea'),
            'text'     => __('Type_list text'),
            'editor'   => __('Type_list editor'),
            'number'   => __('Type_list number'),
            'date'     => __('Type_list date'),
            'time'     => __('Type_list time'),
            'datetime' => __('Type_list datetime'),
            'select'   => __('Type_list select'),
            'selects'  => __('Type_list selects'),
            'image'    => __('Type_list image'),
            'images'   => __('Type_list images'),
            'file'     => __('Type_list file'),
            'files'    => __('Type_list files'),
            'switch'   => __('Type_list switch'),
            'checkbox' => __('Type_list checkbox'),
            'radio'    => __('Type_list radio'),
            'city'     => __('Type_list city')
        ];
    }

    public function getAutofillList()
    {
        return ['0' => __('Autofill 0'), '1' => __('Autofill 1')];
    }

    public function getAutofillTextAttr($value, $data)
    {
        $value = $value ?: ($data['autofill'] ?? '');
        $list  = $this->getAutofillList();
        return $list[$value] ?? '';
    }

    public function getStatusList()
    {
        return ['0' => __('Status 0'), '1' => __('Status 1')];
    }

    public function getIsbasicinfoList()
    {
        return ['0' => __('Isbasicinfo 0'), '1' => __('Isbasicinfo 1')];
    }

    public function getIsbasicinfoTextAttr($value, $data)
    {
        $value = $value ?: ($data['isbasicinfo'] ?? '');
        $list  = $this->getIsbasicinfoList();
        return $list[$value] ?? '';
    }


    public function getTypeListTextAttr($value, $data)
    {
        $value = $value ?: ($data['type_list'] ?? '');
        $list  = $this->getTypeListList();
        return $list[$value] ?? '';
    }

    public function getPositionTextAttr($value, $data)
    {
        $value = $value ?: ($data['position'] ?? '');
        $list  = $this->getPositionList();
        return $list[$value] ?? '';
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ?: ($data['status'] ?? '');
        $list  = $this->getStatusList();
        return $list[$value] ?? '';
    }

}
